package com.ofhb.test;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;

public class AppUtils {
	private Map<String, Object> map = new HashMap<String, Object>();
	
	public AppUtils() {

	} 
	
	public <T> T copyClass(T src, T dest) {

		Field[] destFields = dest.getClass().getDeclaredFields();

		Field[] srcFields = src.getClass().getDeclaredFields();

		for (int i = 0; i < srcFields.length; i++) {
			Field srcField = srcFields[i];
			Field destField = destFields[i];
			Object valueSrc;

			try {
				valueSrc = PropertyUtils.getProperty(src, srcField.getName());
				if(valueSrc != null) {
					if (srcField.getType().getName().toLowerCase().contains("dto") || srcField.getType().getName().toLowerCase().contains("entity")) {
						Object destObj = Class.forName(destField.getType().getName(), true, destField.getType().getClassLoader()).newInstance();
						copyClass(valueSrc, destObj);
						PropertyUtils.setProperty(dest, destField.getName(), destObj);
					} else {
						PropertyUtils.setProperty(dest, destField.getName(), valueSrc);
					}
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return src;
	}

	public <T> T printClassValues(T src) {

		Field[] srcFields = src.getClass().getDeclaredFields();
		Object valueSrc;
		for (int i = 0; i < srcFields.length; i++) {
			Field srcField = srcFields[i];

			try {
				valueSrc = PropertyUtils.getProperty(src, srcField.getName());

				if (valueSrc != null) {
					System.out.println(src.getClass().getCanonicalName() + "." + srcField.getName() + "() => " + valueSrc.toString());
					if (srcField.getType().getName().contains("dto") || srcField.getType().getName().toLowerCase().contains("entity")) {
						printClassValues(valueSrc);
					}
				} else {
					System.out.println(src.getClass().getCanonicalName() + "." + srcField.getName() + "() => NULL");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return src;
	}
	
	
	@SuppressWarnings("unchecked")
    public <T> T  mapClassValues(T src) {
		
		Field[] srcFields = src.getClass().getDeclaredFields();
		Object valueSrc;
		for (int i = 0; i < srcFields.length; i++) {
			Field srcField = srcFields[i];

			try {
				valueSrc = PropertyUtils.getProperty(src, srcField.getName());

				if (valueSrc != null) {
					System.out.println(src.getClass().getCanonicalName() + "." + srcField.getName() + "() => " + valueSrc.toString());
					
					if (srcField.getType().getName().contains("dto") || srcField.getType().getName().contains("entities")) {
						getMap().put(src.getClass().getCanonicalName() + "." + srcField.getName() , printClassValues(valueSrc));
					} else {
						getMap().put(src.getClass().getCanonicalName() + "." + srcField.getName() , valueSrc);
					}
						
				} else {
					getMap().put(src.getClass().getCanonicalName() + "." + srcField.getName() , null);
					System.out.println(src.getClass().getCanonicalName() + "." + srcField.getName() + "() => NULL");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return (T) getMap();
	}

	public Map<String, Object> getMap() {
		if(map == null) {
			map = new HashMap<String, Object>();
		}
	    return map;
    }

}
